console.log('------------------------------------------------------------------');
function *generatorFunc(){
    yield;
}
let generatorObj = generatorFunc();
console.log(generatorObj.next());//{ value: undefined, done: false }
console.log(generatorObj.next());//{ value: undefined, done: true }

function *generatorFunc1(){
    yield 'foo';
    yield 'bar';
    return 'bz';
}
let generatorObj1 = generatorFunc1();
console.log(generatorObj1.next());//{ value: 'foo', done: false }
console.log(generatorObj1.next());//{ value: 'bar', done: false }
console.log(generatorObj1.next());//{ value: 'bz', done: true }

let generatorObj2 = generatorFunc1();
console.log(generatorObj2.next());//{ value: 'foo', done: false }
console.log(generatorObj2.next());//{ value: 'bar', done: false }
console.log(generatorObj2.next());//{ value: 'bz', done: true }

console.log('------------------1. 生成器对象作为可迭代对象-------------------------');
function * generatorFunc2(){
    yield 1;
    yield 2;
    yield 3;
    yield 4;
}
for(let x of generatorFunc2()){
    console.log(x);
}
// 1
// 2
// 3
// 4

function * generatorFunc3(str){
    for(let index=0 ; index < str.length; index++) {
        yield str[index];
    }
}
for(let c of generatorFunc3('abcedfg')){
    console.log(c);
}
// a
// b
// c
// e
// d
// f
// g

console.log('---------------2. 使用 yield 实现输入和输出--------------------------');
function * generatorFunc4(param){
    console.log(param);
    console.log(yield);
    console.log(yield);
    console.log(yield); 
}
let generatorObj4 = generatorFunc4('smith');
generatorObj4.next('first')
generatorObj4.next('second')
generatorObj4.next('third')
generatorObj4.next('fourth')
// smith
// second
// third
// fourth
function * generatorFunc5(){
    return yield 'foo';
}
const generatorObj5 = generatorFunc5();
console.log(generatorObj5.next());//{ value: 'foo', done: false }
console.log(generatorObj5.next('bar'));//{ value: 'bar', done: true }
console.log('----------------------3. 产生可迭代对象--------------------------');
function * generatorFunc6(){
    for(let x of [1,2,3]){
        yield x;
    }
}
for(let x of generatorFunc6()){
    console.log(x);
}
// 1
// 2
// 3
function * generatorFunc7(){
    yield * [1,2,3];
}
for(let x of generatorFunc7()){
    console.log(x);
}
// 1
// 2
// 3
function * generatorFunc8(){
    yield * ['ab','cd','ef'];
    yield * [1,2,3,4];
    yield * ['5','6','7'];
    yield * ['A','B','C','D'];
}
for(let x of generatorFunc8()){
    console.log(x);
}
// ab
// cd
// ef
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// A
// B
// C
// D
function * generatorFunc9(){
    console.log('iter value:',yield * [1,2,3,4]);
}
for(let x of generatorFunc9()){
    console.log('value:',x)
}
// value: 1
// value: 2
// value: 3
// value: 4
// iter value: undefined

function * generatorFunc10(){
    yield 'foo';
    return 'bar';
}
function * generatorFunc11(){
    console.log('iter value:',yield * generatorFunc10())
}
for(let x of generatorFunc11()){
    console.log(x);
}
// foo
// iter value: bar

console.log('-----------------------4. 使用 yield*实现递归算法---------------');
function * generatorFunc12(n){
    if( n>0 ){
        yield * generatorFunc12(n-1);
        yield n-1;
    }
}
for(let x of generatorFunc12(5)){
    console.log(x);
}
// 0
// 1
// 2
// 3
// 4
class Node {
    constructor(id){
        this.id = id;
        this.neighbors = new Set();
    }
    connect(node){
        if(node !== this){
            this.neighbors.add(node);
            node.neighbors.add(this);
        }
    }
}
class RandomGraph {
    constructor(size){
        this.nodes = new Set();
        //创建节点
        for(let i = 0; i < size; ++i){
            this.nodes.add(new Node(i));
        }
        //随机连接节点
        const threshold = 1 / size;
        for(const x of this.nodes){
            for(const y of this.nodes){
                if(Math.random()<threshold){
                    x.connect(y);
                }
            }
        }
    }
    //这个方法仅用于调试
    print(){
        for(const node of this.nodes){
            const ids = [...node.neighbors].map(n=>n.id).join(',');
            console.log(`${node.id}:${ids}`)

        }
    }
}
const g = new RandomGraph(6)
g.print();
// 0:2,4,3
// 1:2
// 2:0,1
// 3:0
// 4:0
// 5: